From 4be7f36712365c25e24414a2704c58e793172e35 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild.aw" Date: Fri, 24 Mar 2006 10:46:14 -0700 Subject: [PATCH] [IA64] Fix domain destroy bug when multiple domains exist Currently vmx irq handler doesn't handle IA64_IPI_VECTOR, which is instead pended to dom0 incorrectly. That bug made people observing system hang when destroying domU with domVTI kept running. Actually there's no need for two different irq handlers, which should be same as long as softirq is checked at exit path back to guest. So remove vmx version here. With this fix, now we can create two domains (domU+domVTI), then destroy domU, create another domVTI, destroy domVTI with all steps successfully finished. Signed-off-by: Xiantao Zhang Signed-off-by: Kevin Tian --- xen/arch/ia64/vmx/Makefile | 1 - xen/arch/ia64/vmx/vmx_irq_ia64.c | 133 ------------------------------- xen/arch/ia64/vmx/vmx_ivt.S | 4 +- 3 files changed, 2 insertions(+), 136 deletions(-) delete mode 100644 xen/arch/ia64/vmx/vmx_irq_ia64.c diff --git a/xen/arch/ia64/vmx/Makefile b/xen/arch/ia64/vmx/Makefile index 55322531b1..df6967be1f 100644 --- a/xen/arch/ia64/vmx/Makefile +++ b/xen/arch/ia64/vmx/Makefile @@ -10,7 +10,6 @@ obj-y += vmx_entry.o obj-y += vmx_hypercall.o obj-y += vmx_init.o obj-y += vmx_interrupt.o -obj-y += vmx_irq_ia64.o obj-y += vmx_ivt.o obj-y += vmx_phy_mode.o obj-y += vmx_process.o diff --git a/xen/arch/ia64/vmx/vmx_irq_ia64.c b/xen/arch/ia64/vmx/vmx_irq_ia64.c deleted file mode 100644 index 319fb3bbee..0000000000 --- a/xen/arch/ia64/vmx/vmx_irq_ia64.c +++ /dev/null @@ -1,133 +0,0 @@ -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include /* for rand_initialize_irq() */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#ifdef CONFIG_SMP -# define IS_RESCHEDULE(vec) (vec == IA64_IPI_RESCHEDULE) -#else -# define IS_RESCHEDULE(vec) (0) -#endif - -#ifdef CONFIG_PERFMON -# include -#endif - -#define IRQ_DEBUG 0 - -#define vmx_irq_enter() \ - add_preempt_count(HARDIRQ_OFFSET); - -/* Now softirq will be checked when leaving hypervisor, or else - * scheduler irq will be executed too early. - */ -#define vmx_irq_exit(void) \ - sub_preempt_count(HARDIRQ_OFFSET); -/* - * That's where the IVT branches when we get an external - * interrupt. This branches to the correct hardware IRQ handler via - * function ptr. - */ -void -vmx_ia64_handle_irq (ia64_vector vector, struct pt_regs *regs) -{ - unsigned long saved_tpr; - int wake_dom0 = 0; - - -#if IRQ_DEBUG - { - unsigned long bsp, sp; - - /* - * Note: if the interrupt happened while executing in - * the context switch routine (ia64_switch_to), we may - * get a spurious stack overflow here. This is - * because the register and the memory stack are not - * switched atomically. - */ - bsp = ia64_getreg(_IA64_REG_AR_BSP); - sp = ia64_getreg(_IA64_REG_AR_SP); - - if ((sp - bsp) < 1024) { - static unsigned char count; - static long last_time; - - if (jiffies - last_time > 5*HZ) - count = 0; - if (++count < 5) { - last_time = jiffies; - printk("ia64_handle_irq: DANGER: less than " - "1KB of free stack space!!\n" - "(bsp=0x%lx, sp=%lx)\n", bsp, sp); - } - } - } -#endif /* IRQ_DEBUG */ - - /* - * Always set TPR to limit maximum interrupt nesting depth to - * 16 (without this, it would be ~240, which could easily lead - * to kernel stack overflows). - */ - vmx_irq_enter(); - saved_tpr = ia64_getreg(_IA64_REG_CR_TPR); - ia64_srlz_d(); - while (vector != IA64_SPURIOUS_INT_VECTOR) { - if (!IS_RESCHEDULE(vector)) { - ia64_setreg(_IA64_REG_CR_TPR, vector); - ia64_srlz_d(); - - if (vector != IA64_TIMER_VECTOR) { - /* FIXME: Leave IRQ re-route later */ - if (!VMX_DOMAIN(dom0->vcpu[0])) - vcpu_pend_interrupt(dom0->vcpu[0],vector); - else - vmx_vcpu_pend_interrupt(dom0->vcpu[0],vector); - wake_dom0 = 1; - } - else { // FIXME: Handle Timer only now - __do_IRQ(local_vector_to_irq(vector), regs); - } - - /* - * Disable interrupts and send EOI: - */ - local_irq_disable(); - ia64_setreg(_IA64_REG_CR_TPR, saved_tpr); - } - ia64_eoi(); - vector = ia64_get_ivr(); - } - /* - * This must be done *after* the ia64_eoi(). For example, the keyboard softirq - * handler needs to be able to wait for further keyboard interrupts, which can't - * come through until ia64_eoi() has been done. - */ - vmx_irq_exit(); - if (wake_dom0 && current->domain != dom0 ) - vcpu_wake(dom0->vcpu[0]); -} diff --git a/xen/arch/ia64/vmx/vmx_ivt.S b/xen/arch/ia64/vmx/vmx_ivt.S index 71c22496cf..7d6906885a 100644 --- a/xen/arch/ia64/vmx/vmx_ivt.S +++ b/xen/arch/ia64/vmx/vmx_ivt.S @@ -551,7 +551,7 @@ ENTRY(vmx_interrupt) movl r14=ia64_leave_nested ;; mov rp=r14 - br.call.sptk.many b6=vmx_ia64_handle_irq + br.call.sptk.many b6=ia64_handle_irq ;; END(vmx_interrupt) @@ -1110,7 +1110,7 @@ ENTRY(vmx_dispatch_interrupt) mov rp=r14 ;; add out1=16,sp // pass pointer to pt_regs as second arg - br.call.sptk.many b6=vmx_ia64_handle_irq + br.call.sptk.many b6=ia64_handle_irq END(vmx_dispatch_interrupt) -- 2.30.2